package com.zjj.learn.designmodel.work.factory.method_factory;

public class MethodFactoryTest {


    public static void main(String[] args) {
        //声明咖啡店
        CoffeeShop shop = new CoffeeShop();
        //创建一个拿铁咖啡工厂
        NatieCoffeeFactory natieCoffeeFactory = new NatieCoffeeFactory();
        //创建一个美式咖啡工厂
        MeishiCoffeeFactory meishiCoffeeFactory = new MeishiCoffeeFactory();
        //使用拿铁咖啡工厂制作咖啡
        shop.setFactory(natieCoffeeFactory);
        //生产了一杯咖啡1【拿铁】
        Coffee coffee1 = shop.order();
        System.out.println("coffee1 = " + coffee1);

        System.out.println("------------------------------");

        //使用美式咖啡工厂制作咖啡
        shop.setFactory(meishiCoffeeFactory);
        //生产一杯咖啡【美式】
        Coffee coffee2 = shop.order();
        System.out.println("coffee2 = " + coffee2);
    }


    /**
     *   工厂方法模式是一种创建型设计模式，它提供了一个抽象的工厂接口，并允许子类自己决定实例化哪个类。
     *   当我们需要根据不同的条件来创建对象时，可以使用工厂方法模式。
     *
     *   工厂方法模式通常由以下几种角色组成：
     *      1、抽象产品 (Product) ：定义产品的属性和行为。
     *      2、具体产品 (Concrete Product) ：实现抽象产品接口的具体类。
     *      3、抽象工厂 (Factory) ：定义工厂的属性和行为以及返回实例化产品的方法。
     *      4、具体工厂 (Concrete Factory) ：实现抽象工厂接口的具体类。
     *
     *
     *   例如：使用工厂方法实现咖啡工厂，具体功能如下
     *      功能描述：
     *        咖啡店可以生产两种咖啡，拿铁咖啡和美食咖啡。
     *        生产咖啡的步骤是 加奶，加糖 然后产生咖啡成品
     *
     *  工厂方法模式的流程如下：
     *     1、创建一个抽象产品类，定义产品的基本属性与方法。
     *          咖啡【Coffee】：抽象类，有名字属性，加奶、加糖两个抽象方法
     *     2、创建一个抽象工厂类，在其中定义一个创建产品的抽象方法。
     *          咖啡工厂【CoffeeFactory】：接口或者抽象类，里面提供生产咖啡的抽象方法
     *     3、创建具体产品类，实现抽象产品接口，即定义具体的产品类型。
     *          美式咖啡【MeishiCoffee】：Coffee 的子类，具体化 Coffee 中的两个方法
     *          拿铁咖啡【NatieCoffee】：Coffee 的子类，具体化 Coffee 中的两个方发
     *     4、创建一个具体工厂类，实现抽象工厂接口，即具体决定应该创建哪种产品。
     *          美式咖啡工厂【MeishiCoffeeFactory】：制作美式咖啡
     *          拿铁咖啡工厂【NatieCoffeeFactory】：制作拿铁咖啡
     *     5、在客户端程序中通过调用具体工厂类的方法来创建产品。
     *          咖啡店【CoffeeShop】：咖啡店，内部聚合了咖啡工厂，提供点单服务，返回具体 Coffee 对象
     *
     *
     *     工厂方法模式可以将具体的产品实现与其它部分的代码分离开来，同时也具备扩展方便、可维护性高等优点。
     *     在需要动态创建对象，并且不知道具体创建哪种对象时，使用工厂方法模式是一种很好的实践方式。
     *
     * 具体实现请见：{@link com.zjj.learn.designmodel.work.factory.method_factory}
     **/
}
